package com.yxx.service.Impl;

import cn.dev33.satoken.stp.StpUtil;
//import co.elastic.clients.elasticsearch._types.query_dsl.CommonTermsQuery;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxx.entity.Talk;
import com.yxx.entityModel.vo.Result.PageResult;
import com.yxx.entityModel.vo.query.PageQuery;
import com.yxx.entityModel.vo.query.TalkQuery;
import com.yxx.entityModel.vo.request.TalkRequest;
import com.yxx.entityModel.vo.response.*;
import com.yxx.enums.FilePathEnum;
import com.yxx.mapper.CommentMapper;
import com.yxx.mapper.TalkMapper;
import com.yxx.service.BlogFileService;
import com.yxx.service.RedisService;
import com.yxx.service.TalkService;
import com.yxx.strategy.context.UploadStrategyContext;
import com.yxx.utils.BeanCopyUtils;
import com.yxx.utils.CommonUtils;
import com.yxx.utils.HTMLUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.yxx.constant.RedisConstant.TALK_LIKE_COUNT;
import static com.yxx.enums.ArticleStatusEnum.PUBLIC;
import static com.yxx.enums.CommentTypeEnum.TALK;

/**
 * @author yuxiangxun
 * @date 2025/2/13
 * @apiNote
 */
@Slf4j
@Service
public class TalkServiceImpl extends ServiceImpl<TalkMapper, Talk> implements TalkService {
    @Resource
    private TalkMapper talkMapper;

    @Resource
    private UploadStrategyContext uploadStrategyContext;

    @Resource
    private BlogFileService blogFileService;

    @Resource
    private RedisService redisService;

    @Resource
    private CommentMapper commentMapper;

    /**
     * 查看后台说说列表
     * @param talkQuery
     * @return
     */
    @Override
    public PageResult<TalkBackResponse> listTalkBackVO(TalkQuery talkQuery) {
        // 查询说说数量
        Long count = talkMapper.selectCount(new LambdaQueryWrapper<Talk>()
                .eq(Objects.nonNull(talkQuery.getStatus()), Talk::getStatus, talkQuery.getStatus()));
        if (count == 0) {
            return new PageResult<>();
        }
        // 分页查询说说列表
        List<TalkBackResponse> talkBackResponseList = talkMapper.selectBackTalkList(talkQuery);
        // 图片数据的格式转换(图片字段忽略的序列化和反序列化的操作)
        // 遍历集合中的每个对象
        talkBackResponseList.forEach(talkBackResponse -> {
            // 转换图片格式 -> 封装图片集合
            if(Objects.nonNull(talkBackResponse.getImages())){
                talkBackResponse.setImgList(
                        CommonUtils.castList(JSON.parseObject(talkBackResponse.getImages(), List.class), String.class)
                );
            }
        });
        return new PageResult<>(talkBackResponseList, count);
    }

    /**
     * 上传说说封面
     * @param file
     * @return
     */
    @Override
    public String uploadTalkCover(MultipartFile file) {
        // 上传文件
        String url = uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.TALK.getPath());
        blogFileService.saveBlogFile(file,url,FilePathEnum.TALK.getFilePath());
        return url;
    }

    /**
     * 添加说说
     * @param talkRequest
     */
    @Override
    public void addTalk(TalkRequest talkRequest) {
        Talk newTalk = BeanCopyUtils.copyBean(talkRequest, Talk.class);
        newTalk.setUserId(StpUtil.getLoginIdAsInt());
        baseMapper.insert(newTalk);
    }

    @Override
    public void deleteTalk(Integer talkId) {
        talkMapper.deleteById(talkId);
    }

    /**
     * 修改说说
     * @param talkRequest
     */
    @Override
    public void updateTalk(TalkRequest talkRequest) {
        Talk newTalk = BeanCopyUtils.copyBean(talkRequest, Talk.class);
        newTalk.setUserId(StpUtil.getLoginIdAsInt());
        baseMapper.updateById(newTalk);
    }

    /**
     * 编辑说说
     * @param talkId
     * @return
     */
    @Override
    public TalkBackInfoResponse editTalk(Integer talkId) {
        TalkBackInfoResponse talkBackVO = talkMapper.selectTalkBackById(talkId);
        // 图片格式转换 封装图片集合
        if(Objects.nonNull(talkBackVO.getImages())){
            talkBackVO.setImgList(
                    CommonUtils.castList(JSON.parseObject(talkBackVO.getImages(),List.class),String.class)
            );
        }
        return talkBackVO;
    }

    /**
     * 查看首页说说
     * @return
     */
    @Override
    public List<String> listTalkHome() {
        // 查看最新5条说说
        List<Talk> talkList = talkMapper.selectList(new LambdaQueryWrapper<Talk>()
                .select(Talk::getTalkContent)
                .eq(Talk::getStatus, PUBLIC.getStatus())
                .orderByDesc(Talk::getIsTop)
                .orderByDesc(Talk::getId)
                .last("limit 5")
        );
        return talkList.stream()
                .map(item -> item.getTalkContent().length() > 200
                        ? HTMLUtils.deleteHtmlTag(item.getTalkContent().substring(0,200))
                        : HTMLUtils.deleteHtmlTag(item.getTalkContent()))
                .collect(Collectors.toList());
    }

    /**
     * 查看说说列表
     * @param pageQuery
     * @return
     */
    @Override
    public PageResult<TalkResponse> listTalkVO(PageQuery pageQuery) {
        // 查看说说公开的数量
        Long count = talkMapper.selectCount(new LambdaQueryWrapper<Talk>()
                .eq(Talk::getStatus, PUBLIC.getStatus()));
        // 如果说说数量为0，返回空分页结果
        if(count == 0){
            return new PageResult<>();
        }
        // 如果说说数量不为0，分页查询说说列表
        List<TalkResponse> talkResponseList = talkMapper.selectTalkList(pageQuery);

        // 因为说说有评论，查询说说的评论量
        // 先提取每条说说的id，封装为集合
        List<Integer> talkIdList = talkResponseList.stream()
                .map(TalkResponse::getId)
                .collect(Collectors.toList());
        // 根据说说id集合和评论类型查询 每条说说的评论量
        List<CommentCountResponse> commentResponses = commentMapper.selectCommentCountByTypeId(talkIdList,TALK.getType());
        // 封装 Map<说说id，评论量>
        Map<Integer, Integer> commentCountMap = commentResponses.stream()
                .collect(Collectors.toMap(CommentCountResponse::getId, CommentCountResponse::getCommentCount));

        // 因为说说可以点赞，封装Map<说说的key,点赞量>
        Map<String,Integer> likeCountMap = redisService.getHashAll(TALK_LIKE_COUNT);

        // 封装说说列表的点赞量和评论量
        talkResponseList.forEach(talkResponse -> {
            talkResponse.setLikeCount(Optional.ofNullable(likeCountMap.get(talkResponse.getId())).orElse(0));
            talkResponse.setCommentCount(Optional.ofNullable(commentCountMap.get(talkResponse.getId())).orElse(0));
            // 转换图片格式
            if(Objects.nonNull(talkResponse.getImages())){
                talkResponse.setImgList(
                        CommonUtils.castList(JSON.parseObject(talkResponse.getImages(),List.class),String.class)
                );
            }
        });

        return new PageResult<>(talkResponseList,count);
    }

    /**
     * 查看说说
     * @param talkId
     * @return
     */
    @Override
    public TalkResponse getTalkById(Integer talkId) {
        // 查询说说信息
        TalkResponse talkResp = talkMapper.selectTalkById(talkId);
        if (Objects.isNull(talkResp)) {
            return null;
        }
        // 查询说说点赞量
        Integer likeCount = redisService.getHash(TALK_LIKE_COUNT, talkId.toString());
        talkResp.setLikeCount(Optional.ofNullable(likeCount).orElse(0));
        // 转换图片格式
        if (Objects.nonNull(talkResp.getImages())) {
            talkResp.setImgList(CommonUtils.castList(JSON.parseObject(talkResp.getImages(), List.class), String.class));
        }
        return talkResp;
    }








}
